package org.vectrics.user.web.struts;

import java.util.Iterator;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.vectrics.SystemException;
import org.vectrics.common.html.Cell;
import org.vectrics.common.html.Row;
import org.vectrics.common.html.Table;
import org.vectrics.common.html.TextHelper;
import org.vectrics.common.http.HttpUtils;
import org.vectrics.common.util.DateUtil;
import org.vectrics.common.util.StringUtils;
import org.vectrics.common.view.FieldTable;
import org.vectrics.company.Company;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.location.Address;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.struts.VectricsTagSupport;
import org.vectrics.user.ContactInfo;
import org.vectrics.user.Person;
import org.vectrics.user.UserPrivilege;

abstract public class UserSummaryTag extends VectricsTagSupport {

    private static final long serialVersionUID = 8451507857473091638L;

    private transient static Logger log = Logger.getLogger(UserSummaryTag.class);

    private String contextPath = null;

    private String compact = "false";

    private String personId = null;

    private boolean showFullName = true;

    private FieldTable fieldTable = null;

    private String showHomeAddress = "true";

    protected abstract boolean showUserPrivileges();

    protected abstract boolean showCompany();

    protected abstract boolean personCanOnlyViewSelf();

    protected void afterUserTable(final Person person) {
        log.debug("No action");
    }

    protected Table getUserInfoTable(final HttpServletRequest request, final Person user) {
        log.debug("getUserInfoTable() - method to make information html table");
        Table mainTable = new Table();
        mainTable.setWidth(620);
        Row mainRow = mainTable.addRow();
        Cell mainCell = mainRow.addCell();

        fieldTable = new FieldTable();
        fieldTable.setCellPadding(2);
        fieldTable.setWidth("100%");
        fieldTable.setValueCellWidth("65%");
        fieldTable.setValueFontClass("stdFont");
        mainCell.addElement(fieldTable);

        if (user.getUser() != null) {
            fieldTable.showField(getPhrase("prompt.user.name"), user.getUser().getUserName());
        } else {
            fieldTable.showField(getPhrase("prompt.user.name"), "-");
        }

        if (showFullName) {
            fieldTable.showField(getPhrase("prompt.full.name"), user.getName());
        } else {
            fieldTable.showField(getPhrase("prompt.first.name"), user.getFirstName());
            fieldTable.showField(getPhrase("prompt.last.name"), user.getLastName());
            fieldTable.showField(getPhrase("prompt.middle.name"), user.getMiddleName());
        }

        makeFieldRow(getPhrase("prompt.name.birthday"), DateUtil.getFechaFormateada(user.getDateOfBirth()));

        if (showCompany()) {
            String companyInfo = "";
            Set companies = CoreServiceLocator.getCompanyService().findCompaniesForPerson(user);
            Iterator compIter = companies.iterator();
            while (compIter.hasNext()) {
                Company company = (Company) compIter.next();
                companyInfo += company.getName();
                if (compIter.hasNext()) {
                    companyInfo += ", ";
                }
            }
            fieldTable.showField(getPhrase("prompt.person.company"), companyInfo);
        }

        if (getCompact().toLowerCase().startsWith("t") == false) {

            if (showUserPrivileges()) {
                if (user.getUser() == null) {
                    makeFieldRow(getPhrase("prompt.user.roles"), getPhrase("phrase.user.roles.none"));
                } else {
                    String roles = "";
                    Iterator iter = user.getPrivileges().iterator();
                    while (iter.hasNext()) {
                        UserPrivilege userPriv = (UserPrivilege) iter.next();
                        roles += userPriv.getPrivilegeType().getName();

                        if (iter.hasNext()) {
                            roles += ",&nbsp;";
                        }
                    }
                    makeFieldRow(getPhrase("prompt.user.roles"), roles);
                }
            }
            makeContactTable(fieldTable, user.getContactInfo());

            String auxStr = "";

            makeFieldRow(getPhrase("prompt.person.cuilOrCuit"), user.getCuilOrCuit());

            auxStr = user.getEmergencyContactName();
            makeFieldRow(getPhrase("prompt.emergency.contact"), auxStr == null || auxStr.length() == 0 ? "-" : auxStr);
            auxStr = user.getEmergencyContactPhoneNumer();
            makeFieldRow(getPhrase("prompt.emergency.phone"), auxStr == null || auxStr.length() == 0 ? "-" : auxStr);
            makeFieldRow("Programming Language",user.getProgrammingLanguage().toString());
            makeFieldRow("English Level",user.getEnglishLevel().toString());
        }
        afterUserTable(user);
        mainTable.setPrettyPrint(true);
        return mainTable;
    }

    protected Person getUserToDisplay(final HttpServletRequest request) {
        Person user = null;
        try {
            if (getPersonId().equals("current")) {
                user = ThreadProperties.getPerson();
            } else {
                user = CoreServiceLocator.getPersonService().findPersonById(new Long(getPersonId()));
            }
            if (user == null) {
                log.debug("Could not find user with id, trying user name");
                String userName = request.getParameter("j_username");
                if (StringUtils.isNullOrBlank(userName)) {
                    userName = request.getParameter("userName");
                    if (StringUtils.isNullOrBlank(userName)) {
                        userName = request.getParameter("username");
                    }
                } else {
                    log.debug("Finding user with login user name");
                }
                if (userName != null) {
                    log.debug("Found user name - finding user");
                    user = CoreServiceLocator.getPersonService().findPersonWithUserName(ThreadProperties.getDomain(),
                            userName);
                    log.info("Found person being viewed: " + user.getName());
                } else {
                    log.info("Could not find person from passed parameters");
                }
            }
        } catch (Exception ex) {
            log.error("doStartTag() - exception finding user, id = " + id, ex);
            throw new SystemException("doStartTag() - exception finding user, id = " + id, ex);
        }

        // if (user == null) {
        // user = this.getAuthPerson();
        // }
        return user;
    }

    /**
     * 
     */
    @Override
    public String makeStartTag() {
        log.debug("doStartTag() called");
        HttpServletRequest request = (HttpServletRequest) super.pageContext.getRequest();
        contextPath = request.getContextPath();
        log.debug("doStartTag() - contextPath = " + contextPath);

        Table mainTable = new Table();
        Row mainRow = mainTable.addRow();
        Cell mainCell = mainRow.addCell();
        Person personToView = getUserToDisplay(request);

        if (personToView != null) {
            mainCell.addElement(getUserInfoTable(request, personToView));
        } else {
            log.error("Error, could not find a user to display. ");
            HttpUtils.logRequestInfo(request, log, Level.ERROR);
        }
        return mainTable.toString();
    }

    protected void makeContactTable(final FieldTable table, final ContactInfo contactInfo) {
        log.debug("getContactTable() - building a table containing contact info");
        String email = "-";
        String email2 = "-";
        String cellPhone = "-";
        String homePhone = "-";
        String workPhone = "-";
        String gender = "-";
        String maritalStatus = "-";

        if (contactInfo != null) {
            email = contactInfo.getEmail();
            email2 = contactInfo.getEmail2();
            if (contactInfo.getCellPhone() != null && contactInfo.getCellPhone().getFormattedNumber().length() != 0) {
                cellPhone = contactInfo.getCellPhone().getFormattedNumber();
            }
            if (contactInfo.getHomePhone() != null && contactInfo.getHomePhone().getFormattedNumber().length() != 0) {
                homePhone = contactInfo.getHomePhone().getFormattedNumber();
            }
            if (contactInfo.getWorkPhone() != null && contactInfo.getWorkPhone().getFormattedNumber().length() != 0) {
                workPhone = contactInfo.getWorkPhone().getFormattedNumber();
            }

            Person person = contactInfo.getPerson();
            gender = person.getGenderDescription(getLocale());
            if (person.getMaritalStatus() != null) {
                maritalStatus = person.getMaritalStatusDescription(getLocale());
            }
        }

        makeFieldRow(getPhrase("prompt.email"), email);
        if (email2 != null && email2.length() > 0) {
            makeFieldRow(getPhrase("prompt.email.2"), email2);
        }

        if (showHomeAddress.startsWith("tr")) {
            if (contactInfo != null) {
                makeAddressRow(table, getPhrase("prompt.home.address"), contactInfo.getHomeAddress());
            } else {
                makeFieldRow(getPhrase("prompt.home.address"), "-");
            }
        }

        makeFieldRow(getPhrase("prompt.mobile.phone"), cellPhone);
        makeFieldRow(getPhrase("prompt.home.phone"), homePhone);
        makeFieldRow(getPhrase("prompt.work.phone"), workPhone);
        makeFieldRow(getPhrase("prompt.person.gender"), gender);
        makeFieldRow(getPhrase("prompt.marital.status"), maritalStatus);
    }

    protected void makeAddressRow(final FieldTable table, final String caption, final Address address) {
        String value = makeAddressHtml(address);
        makeFieldRow(caption, value);
    }

    public static String makeAddressHtml(final Address address) {
        String value = null;
        if (address == null || address.isBlank()) {
            value = null;
        } else {
            if (address.getAddress1() != null) {
                value = address.getAddress1();
            }
            if (address.getAddress2() != null && address.getAddress2().length() > 0) {
                value += "<br>" + address.getAddress2();
            }
            if (address.getCity() != null) {
                value += "<br>" + address.getCity() + ", " + address.getState() + "&nbsp;" + address.getPostalCode();
            }
        }
        return value;
    }

    protected Row makeFieldRow(final String caption, final String value) {
        return fieldTable.showField(caption, value);
        /*
         * log.debug("makeFieldRow() - creating display field in row of html table"
         * ); if (lastBgClass > 1) { lastBgClass = 0; }
         * 
         * if ((value == null) || (value.trim().equals(""))) { value = "<i>" +
         * this.getPhrase("phrase.not.given") + "</i>"; } Row row =
         * table.addRow(); Cell labelCell = row.addCell();
         * labelCell.setVAlign("top");
         * labelCell.addElement(TextHelper.getFont("stdFont", caption));
         * 
         * 
         * Cell cell2 = row.addCell();
         * cell2.addElement(TextHelper.getFont("stdFont", value)); if
         * (lastBgClass == 0) { labelCell.setClass("formBg1");
         * cell2.setClass("formBg1"); } else { labelCell.setClass("formBg2");
         * cell2.setClass("formBg2"); } lastBgClass++; return(row);
         */
    }

    private String getAddressHtml(final HttpServletRequest request, final Address address) {
        log.debug("getAddressHtml() called");
        String str = "<i>No Address Entered</i>";
        if (address != null) {
            if (address.getAddress1() != null && address.getAddress1().length() > 0) {
                str = TextHelper.escapeHtml(address.getAddress1()) + "<br>";
            }
            if (address.getAddress2() != null && address.getAddress2().length() > 0) {
                str += TextHelper.escapeHtml(address.getAddress2()) + "<br>";
            }
            if (address.getCity() != null && address.getCity().length() > 0) {
                str += TextHelper.escapeHtml(address.getCity()) + ", ";
            }
            if (address.getState() != null && address.getState().length() > 0) {
                str += TextHelper.escapeHtml(address.getState()) + ", ";
            }
            if (address.getPostalCode() != null && address.getPostalCode().length() > 0) {
                str += TextHelper.escapeHtml(address.getState()) + "&nbsp;&nbsp;";
            }
            if (str.length() > 0) {
                str += "<br>";
            }
            if (address.getCountryCode() != null && address.getCountryCode().length() > 0) {
                str += TextHelper.escapeHtml(address.getCountryCode()) + "&nbsp;&nbsp;";
            }

            if (str.length() <= 0) {
                str = "<i>" + getPhrase("phrase.not.given") + "</i>";
            }
        }
        return str;
    }

    public String getPersonId() {
        return personId;
    }

    public void setPersonId(final String id) {
        personId = id;
    }

    /**
     * @return Returns the compact.
     */
    public String getCompact() {
        return compact;
    }

    /**
     * @param compact
     *            The compact to set.
     */
    public void setCompact(final String compact) {
        this.compact = compact;
    }

    /**
     * @return Returns the showHomeAddress.
     */
    public String getShowHomeAddress() {
        return showHomeAddress;
    }

    /**
     * @param showHomeAddress
     *            The showHomeAddress to set.
     */
    public void setShowHomeAddress(final String showHomeAddress) {
        this.showHomeAddress = showHomeAddress;
    }

}